﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using BlackBox.Properties;

namespace BlackBox
{
    class Driver
    {
        private const decimal InvestmentAmount = 500m;
        private static readonly Tuple<decimal, decimal> ThresholdPercentageRange = new Tuple<decimal, decimal>(.001m, 0m);
        static void Main()
        {
            var directory = Settings.Default.InputFileDirectory;
            var inputFiles = Directory.EnumerateFiles( directory, "*.csv" );
            var outputFileName = String.Format( "BlackBoxOutput_{0}.txt", DateTime.UtcNow.ToString( "yyyyMMdd-HH.mm.ss" ) );
            var builder = new StringBuilder();

            foreach (var inputFile in inputFiles)
            {
                builder.AppendFormat( "For file {0}{1}", inputFile, Environment.NewLine );
                var profitSummary = GetProfitSummary( inputFile );
                builder.AppendLine( PrintProfitSummary( profitSummary ) );
                builder.AppendLine();
            }

            File.WriteAllText( Path.Combine( directory, outputFileName ), builder.ToString() );
        }

        private static IDictionary<decimal, Dictionary<MinuteInterval, decimal>> GetProfitSummary(string inputFilePath)
        {
            var profitSummary = new Dictionary<decimal, Dictionary<MinuteInterval, decimal>>();
            var analyses = CsvParser.HydrateAnalyses( inputFilePath );
            for (decimal thresholdPercentage = ThresholdPercentageRange.Item1; thresholdPercentage >= ThresholdPercentageRange.Item2; thresholdPercentage -= .00005m)
            {
                var currentProfitSummary = new Dictionary<MinuteInterval, decimal>();
                var decisionEngine = new DecisionEngine(thresholdPercentage);
                foreach (MinuteInterval interval in Enum.GetValues(typeof(MinuteInterval)))
                {
                    currentProfitSummary[interval] = 0.0m;
                    foreach (var analysisData in analyses)
                    {

                        var action = decisionEngine.MakeDecision(analysisData, interval);
                        currentProfitSummary[interval] += ExecutionEngine.ExecuteAndRealizeTrade(InvestmentAmount,
                                                                                           analysisData.
                                                                                               ActualChangePercentage[
                                                                                                   interval],
                                                                                           action);
                    }
                }

                profitSummary.Add(thresholdPercentage, currentProfitSummary);
            }
            return profitSummary;
        }

        private static string PrintProfitSummary(IDictionary<decimal, Dictionary<MinuteInterval, decimal>> profitSummaries)
        {
            var sb = new StringBuilder();
            foreach (var thresholdPercentage in profitSummaries.Keys)
            {
                sb.AppendFormat( "** Threshold Percentage: {0}%{1}", thresholdPercentage * 100, Environment.NewLine );
                var profitSummary = profitSummaries[thresholdPercentage];
                foreach (var minuteInterval in profitSummary.Keys)
                {
                    sb.AppendFormat( "Action at {0} minutes yields {1:c4} profit.{2}",
                                     minuteInterval, profitSummary[minuteInterval], Environment.NewLine );
                }
            }
            return sb.ToString();
        }
    }
}
